package com.tim.javaApi.concurrent;



import com.google.common.util.concurrent.RateLimiter;
import com.google.common.util.concurrent.SimpleTimeLimiter;

import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class Concurrent {
  public static void main(String[] args) throws InterruptedException {
      MyThreadPool mtp = new MyThreadPool(3, 4, 3 * 1000, TimeUnit.MICROSECONDS, new ArrayBlockingQueue(20));
      Runnable r = new Runnable() {
          @Override
          public void run() {
              System.out.println("hello");
              throw new RuntimeException("world");
          }
      };
      mtp.execute(r);
    System.out.println("end");
    Thread.sleep(3000);
    System.exit(1);// main为守护线程，需手动关闭
  }

  static class MyThreadPool extends ThreadPoolExecutor {

      public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
          super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
      }

      private Runnable wrap(Runnable task,Exception logExp,String tName) {
          return new Runnable() {
              public void run() {
                  try { task.run();
                  } catch (Exception e) {
                      logExp.printStackTrace();
                      throw e; } } };  }

      @Override
      public void execute(Runnable command) {
          command = wrap(command, new RuntimeException(), Thread.currentThread().getName());
          super.execute(command);
      }
  }

    public static void thread(){
        Runnable runnable;
        Thread thread = new Thread();
        // 中断时通知线程，由线程决定如何处理中断。
        // 阻塞中的线程，只抛异常，中断不置位；如需判定中断，再次中断线程 Thread.currentThread().interrupt();
        // 运行中线程，中断置true
        thread.interrupt();
        Thread.interrupted();// 调用后中断置false
        thread.isInterrupted();// 调用后不重置中断标志

        ThreadLocal tl;

        Executor executor;
        Executors executors;// 工具类
        ExecutorService executorService;
        Callable callable;
        Future future;

        ThreadPoolExecutor tpe;
        ScheduledThreadPoolExecutor stpe;
        ForkJoinPool fj;
    }

    /**
     * synchronized；基于jvm
     * LockSupport；基于硬件指令
     *  Lock；synchronized
     *  Condition；监视器操作
     */
    public static void lock(){
        // 锁
        Lock lock;
        ReentrantLock reentrantLock;
        LockSupport lockSupport;

        // 读写锁
        ReadWriteLock readWriteLock;
        ReentrantReadWriteLock reentrantReadWriteLock;

        //
        StampedLock stampedLock;

        // 锁实现框架；锁对象，等待队列，
        AbstractQueuedSynchronizer aqs;
    }

    /**
     * 线程间通信
     */
    public static void coordinate() throws Exception {
        /*
         * synchronized监视器；监视器包含阻塞队列、等待队列
         *  1，obj未被占用，获取obj监视器
         *  2，obj已被占用，阻塞线程，不释放已持有监视器；加入阻塞队列，等待JVM唤醒
         *  3，Object#wait；阻塞线程，释放obj监视器(必须持有obj监视器)，加入等待队列，等待notify将其移入阻塞队列
         *  4，Object#notify；不释放监视器、不阻塞线程，将obj监视器等待队列中元素移入阻塞队列
         *  5，释放监视器：同步代码结束、Object#wait
         */
        Object obj = null;
        synchronized (obj){
            // 可能虚假唤醒，应在循环中使用；通过额外条件判定是否满足唤醒条件
            obj.wait(0);
            obj.notify();
            obj.notifyAll();
        }


        /*
         * Thread api
         */
        Thread thread=null;
        thread.join(0);// 为同步方法，调用thread.wait暂停当前线程，thread线程终止时自动调用notifyAll
        Thread.sleep(1);// 阻塞线程，不丢失监视器
        Thread.yield();// 让步，加入OS线程调度列表；不丢失监视器

        /*
         * Lock，synchronized。lock获取监视器，unlock释放监视器
         * Condition，监视器。await释放监视器，signal唤醒等待的线程
         * AbstractQueuedSynchronizer中，Node自链表作阻塞队列
         */
        Lock lock=null;
        lock.lock();
        lock.unlock();

        // AbstractQueuedSynchronizer.Node自链表，作等待队列；持有head、tail
        Condition condition=lock.newCondition();
        condition.await();
        condition.signal();// 从等待队列，移入阻塞队列
        condition.signalAll();

    }


    /**
     * 并发工具集
     */
    public static void concurrentUtil() throws Exception {
        // 集合；阻塞队列
        SynchronousQueue synchronousQueue;// 同步队列
        LinkedTransferQueue linkedTransferQueue;// 无界阻塞队列
        LinkedBlockingQueue linkedBlockingQueue;// 一个正常的基于链表结构的阻塞队列， 无界队列.
        LinkedBlockingDeque linkedBlockingDeque;// 双向链表组成的队列

        // 线程协调
        Semaphore semaphore=new Semaphore(3);// 信号量。令牌桶，限流
        semaphore.acquire();// 获取许可，无时阻塞
        semaphore.release();// 释放许可
        CountDownLatch countDownLatch=new CountDownLatch(5);// 倒计数
        countDownLatch.await();// 阻塞线程，直到倒计数为0
        countDownLatch.countDown();// 倒计数-1；计数达到零，则释放所有等待的线程。
        CyclicBarrier cyclicBarrier=new CyclicBarrier(5);// 循环栅栏；可重置的CountDownLatch
        cyclicBarrier.await();// 计数-1；阻塞线程，直到倒计数为0
        cyclicBarrier.reset();// 重置计数
    }

  /**
   * com.google.guava#guava
   */
  public static void googleConcurrent() {
      RateLimiter rl;// 漏桶
      SimpleTimeLimiter stl;// 限时器

    }


}
